package net.wicp.tams.commons.binlog.constant;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import net.wicp.tams.commons.beans.Host;
import net.wicp.tams.commons.binlog.event.AbsEvent;

public enum EventType {
	UNKNOWN_EVENT("不明事件", (byte) 0x00), // 在FORMAT_DESCRIPTION_EVENT事件
										// 中没有这个事件，便把Binlog Event
										// Header安在这里了

	START_EVENT_V3("", (byte) 0x01, 0),

	QUERY_EVENT("", (byte) 0x02, 1),

	STOP_EVENT("文件已完成事件", (byte) 0x03, 2, "net.wicp.tams.commons.binlog.event.StopEvent"),

	ROTATE_EVENT("跳转事件", (byte) 0x04, 3, "net.wicp.tams.commons.binlog.event.RotateEvent"),

	INTVAR_EVENT("", (byte) 0x05, 4),

	LOAD_EVENT("", (byte) 0x06, 5),

	SLAVE_EVENT("", (byte) 0x07, 6),

	CREATE_FILE_EVENT("", (byte) 0x08, 7),

	APPEND_BLOCK_EVENT("", (byte) 0x09, 8),

	EXEC_LOAD_EVENT("", (byte) 0x0a, 9),

	DELETE_FILE_EVENT("", (byte) 0x0b, 10),

	NEW_LOAD_EVENT("", (byte) 0x0c, 11),

	RAND_EVENT("", (byte) 0x0d, 12),

	USER_VAR_EVENT("", (byte) 0x0e, 13),

	FORMAT_DESCRIPTION_EVENT("", (byte) 0x0f, 14, "net.wicp.tams.commons.binlog.event.FormatDescription"),

	XID_EVENT("", (byte) 0x10, 15, "net.wicp.tams.commons.binlog.event.XidEvent"),

	BEGIN_LOAD_QUERY_EVENT("", (byte) 0x11, 16),

	EXECUTE_LOAD_QUERY_EVENT("", (byte) 0x12, 17),

	TABLE_MAP_EVENT("", (byte) 0x13, 18, "net.wicp.tams.commons.binlog.event.TableMapEvent"),

	WRITE_ROWS_EVENTv0("", (byte) 0x14, 21),

	UPDATE_ROWS_EVENTv0("", (byte) 0x15, 20),

	DELETE_ROWS_EVENTv0("", (byte) 0x16, 19),

	WRITE_ROWS_EVENTv1("", (byte) 0x17, 24, "net.wicp.tams.commons.binlog.event.rows.write.WriteRowsEventV1"),

	UPDATE_ROWS_EVENTv1("", (byte) 0x18, 23, "net.wicp.tams.commons.binlog.event.rows.update.UpdateRowsEventV1"),

	DELETE_ROWS_EVENTv1("", (byte) 0x19, 22, "net.wicp.tams.commons.binlog.event.rows.delete.DeleteRowsEventV1"),

	INCIDENT_EVENT("", (byte) 0x1a, 25),

	HEARTBEAT_EVENT("", (byte) 0x1b, 26),

	IGNORABLE_EVENT("", (byte) 0x1c), ////////////////////////

	ROWS_QUERY_EVENT("", (byte) 0x1d), //////////////////////

	WRITE_ROWS_EVENTv2("", (byte) 0x1e, 29, "net.wicp.tams.commons.binlog.event.rows.write.WriteRowsEventV2"),

	UPDATE_ROWS_EVENTv2("", (byte) 0x1f, 28, "net.wicp.tams.commons.binlog.event.rows.update.UpdateRowsEventV2"),

	DELETE_ROWS_EVENTv2("", (byte) 0x20, 27, "net.wicp.tams.commons.binlog.event.rows.delete.DeleteRowsEventV2"),

	GTID_EVENT("", (byte) 0x21), ///////////////////////////////////

	ANONYMOUS_GTID_EVENT("", (byte) 0x22), //////////////////////////////

	PREVIOUS_GTIDS_EVENT("", (byte) 0x23);//////////////////////////////////

	private final String desc;
	private final byte value;// 值
	private final int formatIndex;// 在 FORMAT_DESCRIPTION_EVENT事件中的位置，从1开始
	// private int postHeaderLength = -1;// 在FORMAT_DESCRIPTION_EVENT中定信的字段长度
	private final String parser;
	private final Map<Host, Integer> headerLengthMap = new HashMap<>();

	private final static Set<Host> hostset = new HashSet<>();

	private EventType(String desc, byte value, int formatIndex, String parser) {
		this.desc = desc;
		this.value = value;
		this.formatIndex = formatIndex;
		this.parser = parser;
	}

	private EventType(String desc, byte value, int formatIndex) {
		this.desc = desc;
		this.value = value;
		this.formatIndex = formatIndex;
		this.parser = null;
	}

	private EventType(String desc, byte value) {
		this.desc = desc;
		this.value = value;
		this.formatIndex = -1;
		this.parser = null;
	}

	public static EventType get(byte val) {
		if (val > (byte) 0x23) {
			return null;
		}
		for (EventType eventType : EventType.values()) {
			if (eventType.getValue() == val) {
				return eventType;
			}
		}
		return null;
	}

	/***
	 * 排列，为得到EventType的类型
	 * 
	 * @return
	 */
	public static EventType[] orderFormat() {
		EventType[] retary = new EventType[30];
		for (EventType eventType : EventType.values()) {
			if (eventType.getFormatIndex() < 0) {
				continue;
			} else {
				retary[eventType.getFormatIndex()] = eventType;
			}
		}
		return retary;
	}

	public static boolean isInit(Host host) {
		return hostset.contains(host);
	}

	public int getPostHeaderLength() {
		Host host = AbsEvent.hosts.get();
		Integer retobj = headerLengthMap.get(host);
		return host == null || retobj == null ? -1 : retobj.intValue();
	}

	public void setPostHeaderLength(int postHeaderLength) {
		Host host = AbsEvent.hosts.get();
		if (host == null) {
			throw new IllegalAccessError("没有得到主机，不能做设置");
		}
		hostset.add(host);
		headerLengthMap.put(host, postHeaderLength);
	}

	public String getDesc() {
		return desc;
	}

	public byte getValue() {
		return value;
	}

	public int getFormatIndex() {
		return formatIndex;
	}

	public String getParser() {
		return parser;
	}
}
